package org.linlinjava.litemall.admin.service;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.linlinjava.litemall.admin.controller.charge.vo.AdminRechargeTransactionsRespVO;
import org.linlinjava.litemall.admin.vo.charge.ChargeListRespVO;
import org.linlinjava.litemall.admin.vo.charge.ChargeReqVO;
import org.linlinjava.litemall.admin.vo.charge.ChargeSummaryRespVO;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.beans.Constants;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.service.*;
import org.linlinjava.litemall.db.util.BeanUtil;
import org.linlinjava.litemall.db.util.CollectionUtils;
import org.linlinjava.litemall.db.util.MapUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Service
@Transactional
@Slf4j
@RequiredArgsConstructor
public class AdminChargeService {

    private final LitemallGiftCardOrderService litemallGiftCardOrderService;
    private final LitemallGiftCardUserLogService litemallGiftCardUserLogService;
    private final LitemallRechargeConsumptionService litemallRechargeConsumptionService;
    private final LitemallRechargeTransactionsService litemallRechargeTransactionsService;
    private final LitemallShopService litemallShopService;
    private final LitemallUserService litemallUserService;

    public ResponseUtil.Response getTotalChargeSummary(ChargeReqVO reqVO) {
        BigDecimal appAmount = BigDecimal.ZERO; // 线上 APP 充值总额
        BigDecimal posAmount = BigDecimal.ZERO; // 线下 POS 充值总额

        List<LitemallRechargeTransactions> rechargeTransactionsList = litemallRechargeTransactionsService.list();

        for (LitemallRechargeTransactions rechargeTransactions : rechargeTransactionsList) {
            if (rechargeTransactions.getPayType() == Constants.PAY_TYPE_CASH) {
                // 线下 POS 充值
                posAmount = posAmount.add(rechargeTransactions.getRechargeAmount());
            } else {
                // 线上 APP 充值
                appAmount = appAmount.add(rechargeTransactions.getRechargeAmount());
            }
        }

        // 创建一个响应对象，封装总计信息
        ChargeSummaryRespVO summaryResp = new ChargeSummaryRespVO();
        summaryResp.setAppAmount(appAmount);
        summaryResp.setPosAmount(posAmount);
        summaryResp.setTotalAmount(appAmount.add(posAmount)); // 总充值金额

        // 返回结果
        return ResponseUtil.ok(summaryResp);
    }


    public ResponseUtil.Response getChargeList(ChargeReqVO reqVO) {
        List<ChargeListRespVO> chargeList =new ArrayList<>();
        //所有门店
        LambdaQueryWrapper<LitemallShop> shopLambdaQueryWrapper = new LambdaQueryWrapper<>();
        shopLambdaQueryWrapper.eq(reqVO.getShopId()!=null,LitemallShop::getId,reqVO.getShopId());
        IPage<LitemallShop> shopList = litemallShopService.selectShopPage( shopLambdaQueryWrapper, reqVO.getPage(), reqVO.getLimit());
        for (LitemallShop shop : shopList.getRecords()) {
            ChargeListRespVO respVO = new ChargeListRespVO();
            respVO.setShopId(shop.getId());
            respVO.setShopName(shop.getName());

            BigDecimal appAmount = BigDecimal.ZERO;
            BigDecimal posAmount = BigDecimal.ZERO;

            List<LitemallRechargeTransactions> rechargeTransactionsList = litemallRechargeTransactionsService.list(Wrappers.lambdaQuery(LitemallRechargeTransactions.class)
                    .eq(LitemallRechargeTransactions::getPayType, Constants.PAY_TYPE_CASH)
                    .eq(LitemallRechargeTransactions::getShopId,shop.getId()));
            for (LitemallRechargeTransactions rechargeTransactions : rechargeTransactionsList) {
                posAmount=posAmount.add(rechargeTransactions.getRechargeAmount());
            }
            respVO.setAppAmount(appAmount);
            respVO.setPosAmount(posAmount);
            chargeList.add(respVO);
        }
        return ResponseUtil.okPage(shopList,chargeList);
    }

    public ResponseUtil.Response getHQChargeList() {
        List<ChargeListRespVO> chargeList =new ArrayList<>();
        //总店
        List<LitemallRechargeTransactions> rechargeTransactionsList = litemallRechargeTransactionsService.list(Wrappers.lambdaQuery(LitemallRechargeTransactions.class));
        // 使用Stream API将amount属性值加起来
        BigDecimal totalAmount = rechargeTransactionsList.stream()
                .filter(item->item.getPayType()!=Constants.PAY_TYPE_CASH)
                .map(LitemallRechargeTransactions::getRechargeAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        chargeList.add(new ChargeListRespVO().setShopName("总店所有").setPosAmount(BigDecimal.ZERO).setAppAmount(totalAmount));
        return ResponseUtil.okList(chargeList);
    }

    public ResponseUtil.Response getShopChargeList(ChargeReqVO reqVO) {
        LambdaQueryWrapper<LitemallUser> userQueryWrapper = new LambdaQueryWrapper<>();
        Optional.ofNullable(reqVO.getUsername()).ifPresent(val -> userQueryWrapper.eq(LitemallUser::getUsername, val));
        Optional.ofNullable(reqVO.getNickname()).ifPresent(val -> userQueryWrapper.eq(LitemallUser::getNickname, val));
        List<LitemallUser> userList = litemallUserService.list(userQueryWrapper);

        LambdaQueryWrapper<LitemallRechargeTransactions> lambda = new LambdaQueryWrapper<>();
        Optional.ofNullable(reqVO.getRechargeType()).ifPresent(val -> lambda.eq(LitemallRechargeTransactions::getRechargeType, val));
        Optional.ofNullable(reqVO.getRechargeSource()).ifPresent(val -> lambda.eq(LitemallRechargeTransactions::getRechargeSource, val));
        Optional.ofNullable(reqVO.getPayType()).ifPresent(val -> lambda.eq(LitemallRechargeTransactions::getPayType, val));
        if(CollUtil.isNotEmpty(userList)){
            lambda.in(LitemallRechargeTransactions::getUserId, CollectionUtils.convertSet(userList,LitemallUser::getId));
        }

        Optional.ofNullable(reqVO.getCardNo()).filter(StrUtil::isNotEmpty).ifPresent(val -> lambda.like(LitemallRechargeTransactions::getCardNo, val));
        if (reqVO.getShopId() == null) {
            lambda.ne(LitemallRechargeTransactions::getPayType, Constants.PAY_TYPE_CASH);
        } else {
            lambda.eq(LitemallRechargeTransactions::getShopId, reqVO.getShopId());
        }
        Optional.ofNullable(reqVO.getDateRange())
                .filter(arr -> arr.length == 2 && arr[0] != null && arr[1] != null)
                .ifPresent(range -> lambda.between(LitemallRechargeTransactions::getAddTime, range[0], range[1]));
        IPage<LitemallRechargeTransactions> rechargeTransactionsList = litemallRechargeTransactionsService.page(new Page<>(reqVO.getPage(), reqVO.getLimit()), lambda);
        Map<Integer, LitemallUser> userMap = litemallUserService.getUserMap(CollectionUtils.convertSet(rechargeTransactionsList.getRecords(), LitemallRechargeTransactions::getUserId));

        Page<AdminRechargeTransactionsRespVO> adminRechargeTransactionsRespPage = BeanUtil.copyPage(rechargeTransactionsList, AdminRechargeTransactionsRespVO.class);
        adminRechargeTransactionsRespPage.getRecords().forEach(item->{
            MapUtils.findAndThen(userMap,item.getUserId(),user->{
                item.setNickname(user.getNickname());
                item.setUsername(user.getUsername());
            });
        });
        return ResponseUtil.okPage(adminRechargeTransactionsRespPage);
    }
}
